package fhv.itb.ec.auction;

import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
import java.util.Vector;
import javax.naming.InitialContext;

public class AuctionServer extends UnicastRemoteObject implements Runnable, Auction {

	private static final long serialVersionUID = -7252111324023239826L;

	private Vector<ClientInterface> m_clients; // tracks all connected clients
	private ClientInterface m_clientObj;
	
	//Server knows implementation
	private AuctionImpl1 m_auctionImpl = null;
	
	private Thread clientThread = null;


	public AuctionServer() throws java.rmi.RemoteException, IOException {
		super();

		m_auctionImpl = new AuctionImpl1();
		m_clients = new Vector<ClientInterface>();
	}

	//Method for adding client and starting thread
	public void setClientInterface(ClientInterface c) throws RemoteException {
		synchronized (m_clients) {
			m_clients.addElement(c);
		}
		if (clientThread == null) {
			clientThread = new Thread(this, "clientThread");
			clientThread.start();
		}
	}


	
	public void refresh() {
		synchronized (m_clients) {
			//making working copy
			Vector<ClientInterface> backup = (Vector<ClientInterface>) m_clients.clone();
			
			//Get the Item and the price of the last bid
			String item = m_auctionImpl.getLastBidItem();
			Integer actualBid = m_auctionImpl.getLastBid();
			
			//for all clients
			for (int j = 0; j < m_clients.size(); j++) {
				//Getting client object
				m_clientObj = (ClientInterface) m_clients.elementAt(j);

				try {
					//printing the item and the actual price
					m_clientObj.printActualBidding(item, actualBid);
				} catch (RemoteException e) {
					System.out.println("client must have disconnected!");
					// get rid of remote reference for disconnected client
					backup.removeElement(m_clientObj);

					if (backup.size() <= 0) {
						// no more clients- so stop server thread
						m_clients = (Vector<ClientInterface>) backup.clone();
						Thread dummy = clientThread;
						clientThread = null;

						// Stop dummy thread
						dummy.interrupt();
					}
				}
			}
			m_clients = (Vector<ClientInterface>) backup.clone();
		} // end syncronization on clients
		
	}


	public void run() {
		while (true) {
			
		}
	}


	public static void main(String[] args) {

		//getting codebase
		String codebase = "http://localhost:8080/Download/";
		System.setProperty("java.rmi.server.codebase", codebase);

		// create JNDI properties
		Hashtable props = new Hashtable();
		props.put("java.naming.factory.initial",
				"com.sun.jndi.rmi.registry.RegistryContextFactory");
		props.put("java.naming.provider.url", "rmi://localhost:1099");

		InitialContext initContext = null;

		try {
			//creating Auctionserver object and bind it in registry
			initContext = new InitialContext(props);
			AuctionServer server = new AuctionServer();
			initContext.rebind("AuctionObject", server);
			System.out.println("AuctionObject bound in registry");
		} catch (Exception e) {
			System.out.println("AuctionImpl error");
			e.printStackTrace();
		}

	}

	//pass on bid method to implementation object
	@Override
	public String bid(String bidderName, String item, int price)
			throws RemoteException {
		return m_auctionImpl.bid(bidderName, item, price);
	}

	//pass on joinAuction method to implementation object
	@Override
	public String joinAuction(String bidderName, String auctionName)
			throws RemoteException {
		return m_auctionImpl.joinAuction(bidderName, auctionName);
	}

	//pass on leaveAuction method to implementation object
	@Override
	public String leaveAuction(String bidderName, String auctionName)
			throws RemoteException {
		return m_auctionImpl.leaveAuction(bidderName, auctionName);
	}

	//Method for printing out an itemList
	@Override
	public String getItemList() throws RemoteException {
		Vector<Item> items = m_auctionImpl.getItems();
		StringBuffer list= new StringBuffer();
		for (int i = 0; i < items.size(); i++) {
			list.append("Item " + items.elementAt(i).getTitle());
			list.append(" current Price is " + items.elementAt(i).getCurrentPrice());
			list.append('\n');
		}
		
		return list.toString();
	}
}
